package cn.exrick.xboot.modules.content.controller;

import cn.exrick.xboot.common.constant.CommonConstant;
import cn.exrick.xboot.common.redis.RedisTemplateHelper;
import cn.exrick.xboot.common.utils.CustomStringUtils;
import cn.exrick.xboot.common.utils.ResultUtil;
import cn.exrick.xboot.common.utils.SecurityUtil;
import cn.exrick.xboot.common.utils.SnowFlakeUtil;
import cn.exrick.xboot.common.vo.Result;
import cn.exrick.xboot.config.security.permission.MySecurityMetadataSource;
import cn.exrick.xboot.modules.base.entity.Permission;
import cn.exrick.xboot.modules.base.entity.RolePermission;
import cn.exrick.xboot.modules.base.entity.User;
import cn.exrick.xboot.modules.base.service.mybatis.IPermissionService;
import cn.exrick.xboot.modules.base.utils.VoUtil;
import cn.exrick.xboot.modules.base.vo.MenuVo;
import cn.exrick.xboot.modules.content.entity.HontPermission;
import cn.exrick.xboot.modules.content.entity.HontRolePermission;
import cn.exrick.xboot.modules.content.entity.HontUser;
import cn.exrick.xboot.modules.content.entity.HontUserPermission;
import cn.exrick.xboot.modules.content.service.HontPermissionService;
import cn.exrick.xboot.modules.content.service.HontRolePermissionService;
import cn.exrick.xboot.modules.content.service.HontUserService;
import cn.exrick.xboot.modules.content.service.IHontUserPermissionService;
import cn.exrick.xboot.modules.content.service.mybatis.IHontPermissionService;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;


/**
 * @author Exrick
 */
@Slf4j
@RestController
@Api(description = "权限管理接口")
@RequestMapping("/xboot/hontPermission")
@Transactional
public class HontPermissionController {

    @Autowired
    private HontRolePermissionService hontRolePermissionService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private IHontPermissionService ihontPermissionService;
    @Autowired
    private HontUserService hontUserService;
    @Autowired
    private HontPermissionService hontPermissionService;
    @Autowired
    private MySecurityMetadataSource mySecurityMetadataSource;
    @Autowired
    private RedisTemplateHelper redisTemplateHelper;
    @Autowired
    private IHontUserPermissionService hontUserPermissionServiceImpl;
    @Autowired
    private SecurityUtil securityUtil;

    @RequestMapping(value = "/getMenuList", method = RequestMethod.GET)
    @ApiOperation(value = "获取前台用户页面菜单数据")
    public Result<List<MenuVo>> getAllMenuList(){

        List<MenuVo> menuList = new ArrayList<>();
        HontUser hontUser = securityUtil.getCurrUser();
        // 读取缓存
      //  HontUser hontUser = hontUserService.get(userId);
/*        String key = "hontPermission::hontUserMenuList:" + hontUser.getId();
        String v = redisTemplate.opsForValue().get(key);
        if(StrUtil.isNotBlank(v)&&!v.equals("[]")){
            menuList = new Gson().fromJson(v, new TypeToken<List<MenuVo>>(){}.getType());
            return new ResultUtil<List<MenuVo>>().setData(menuList);
        }*/

        // 用户所有权限 已排序去重
        List<HontPermission> list = hontUserPermissionServiceImpl.findMenuByUserId(hontUser.getId());

        // 筛选0级页面
        for(HontPermission p : list){
            if(CommonConstant.PERMISSION_NAV.equals(p.getType())&&CommonConstant.LEVEL_ZERO.equals(p.getLevel())){
                menuList.add(VoUtil.hontPermissionToMenuVo(p));
            }
        }
        // 筛选一级页面
        List<MenuVo> firstMenuList = new ArrayList<>();
        for(HontPermission p : list){
            if(CommonConstant.PERMISSION_PAGE.equals(p.getType())&&CommonConstant.LEVEL_ONE.equals(p.getLevel())){
                firstMenuList.add(VoUtil.hontPermissionToMenuVo(p));
            }
        }
        // 筛选二级页面
        List<MenuVo> secondMenuList = new ArrayList<>();
        for(HontPermission p : list){
            if(CommonConstant.PERMISSION_PAGE.equals(p.getType())&&CommonConstant.LEVEL_TWO.equals(p.getLevel())){
                secondMenuList.add(VoUtil.hontPermissionToMenuVo(p));
            }
        }
        // 筛选二级页面拥有的按钮权限
        List<MenuVo> buttonPermissions = new ArrayList<>();
        for(HontPermission p : list){
            if(CommonConstant.PERMISSION_OPERATION.equals(p.getType())&&CommonConstant.LEVEL_THREE.equals(p.getLevel())){
                buttonPermissions.add(VoUtil.hontPermissionToMenuVo(p));
            }
        }

        // 匹配二级页面拥有权限
        for(MenuVo m : secondMenuList){
            List<String> permTypes = new ArrayList<>();
            for(MenuVo me : buttonPermissions){
                if(m.getId().equals(me.getParentId())){
                    permTypes.add(me.getButtonType());
                }
            }
            m.setPermTypes(permTypes);
        }
        // 匹配一级页面拥有二级页面
        for(MenuVo m : firstMenuList){
            List<MenuVo> secondMenu = new ArrayList<>();
            for(MenuVo me : secondMenuList){
                if(m.getId().equals(me.getParentId())){
                    secondMenu.add(me);
                }
            }
            m.setChildren(secondMenu);
        }
        // 匹配0级页面拥有一级页面
        for(MenuVo m : menuList){
            List<MenuVo> firstMenu = new ArrayList<>();
            for(MenuVo me : firstMenuList){
                if(m.getId().equals(me.getParentId())){
                    firstMenu.add(me);
                }
            }
            m.setChildren(firstMenu);
        }

        // 缓存
     //   redisTemplate.opsForValue().set(key, new Gson().toJson(menuList), 15L, TimeUnit.DAYS);
        return new ResultUtil<List<MenuVo>>().setData(menuList);
    }

    @RequestMapping(value = "/getAllList", method = RequestMethod.GET)
    @ApiOperation(value = "获取权限菜单树")
    //@Cacheable(key = "'allList'")
    public Result<List<HontPermission>> getAllList(){
        // 0级
        List<HontPermission> listData = new ArrayList<HontPermission>();
        List<HontPermission> list = hontPermissionService.findFirstLevel();
        for (HontPermission permission : list) {
            if(!CustomStringUtils.isNotBlank(permission.getParentId())){
                List<HontPermission> permissions = childrenPerssion(permission);
                permission.setChildren(permissions);
                listData.add(permission);
            }
        }

        return new ResultUtil<List<HontPermission>>().setData(listData);
    }
    public  List<HontPermission> childrenPerssion(HontPermission permission){
        List<HontPermission> byParentIdOrderBySortOrder = hontPermissionService.findByParentId(permission.getId());
        for(int i=0;i<byParentIdOrderBySortOrder.size();i++){
            List<HontPermission> permissions = childrenPerssion(byParentIdOrderBySortOrder.get(i));
            byParentIdOrderBySortOrder.get(i).setChildren(permissions);

        }
        return byParentIdOrderBySortOrder;
    }
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ApiOperation(value = "添加")
   // @CacheEvict(key = "'menuList'")
    public Result<HontPermission> add(HontPermission permission){

        // 判断拦截请求的操作权限按钮名是否已存在
        if(CommonConstant.PERMISSION_OPERATION.equals(permission.getType())){
            List<HontPermission> list = hontPermissionService.findByTitle(permission.getTitle());
            if(list!=null&&list.size()>0){
                return new ResultUtil<HontPermission>().setErrorMsg("名称已存在");
            }
        }

        if (StringUtils.isNotBlank(permission.getParentId())){
            HontPermission permission1 = hontPermissionService.get(permission.getParentId());
            permission.setLevel(permission1.getLevel() + 1);
            permission.setType(0);
        }else {
            permission.setLevel(0);
            permission.setType(-1);
        }

        permission.setId(String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()));
        permission.setCreateTime(DateTime.now());
        permission.setUpdateTime(DateTime.now());
        HontPermission u = hontPermissionService.save(permission);
        //重新加载权限
       // mySecurityMetadataSource.loadResourceDefine();
        //手动删除缓存
      //  redisTemplate.delete("permission::allList");
        return new ResultUtil<HontPermission>().setData(u);
    }
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    @ApiOperation(value = "编辑")
    public Result<HontPermission> edit(HontPermission permission){

        // 判断拦截请求的操作权限按钮名是否已存在
        if(CommonConstant.PERMISSION_OPERATION.equals(permission.getType())){
            // 若名称修改
            HontPermission p = hontPermissionService.get(permission.getId());
            if(!p.getTitle().equals(permission.getTitle())){
                List<HontPermission> list = hontPermissionService.findByTitle(permission.getTitle());
                if(list!=null&&list.size()>0){
                    return new ResultUtil<HontPermission>().setErrorMsg("名称已存在");
                }
            }
        }
        if (permission.getId() != null){
            HontPermission permission1 = hontPermissionService.get(permission.getId());
            permission.setCreateTime(permission1.getCreateTime());
            permission.setType(permission1.getType());
            permission.setLevel(permission1.getLevel());
            permission.setUpdateTime(DateTime.now());
            HontPermission u = hontPermissionService.update(permission);
            /*mySecurityMetadataSource.loadResourceDefine();
            //手动批量删除缓存
            Set<String> keys = redisTemplateHelper.keys("userPermission:" + "*");
            redisTemplate.delete(keys);
            Set<String> keysUser = redisTemplateHelper.keys("user:" + "*");
            redisTemplate.delete(keysUser);
            Set<String> keysUserMenu = redisTemplateHelper.keys("permission::userMenuList:*");
            redisTemplate.delete(keysUserMenu);
            redisTemplate.delete("permission::allList");*/
            return new ResultUtil<HontPermission>().setData(u);
        }else {
            return ResultUtil.error("该权限不存在");
        }
    }
    @RequestMapping(value = "/delByIds/{ids}", method = RequestMethod.DELETE)
    @ApiOperation(value = "批量通过id删除")
    //@CacheEvict(key = "'menuList'")
    public Result<Object> delByIds(@PathVariable String[] ids){
       for(String id:ids){
            List<HontUserPermission> list = hontUserPermissionServiceImpl.findByPermissionId(id);
            if(list!=null&&list.size()>0){
                return ResultUtil.error("删除失败，包含正被角色使用关联的菜单或权限");
            }
        }
        for(String id:ids){
            hontPermissionService.delete(id);
        }
        //重新加载权限
    /*    mySecurityMetadataSource.loadResourceDefine();
        //手动删除缓存
        redisTemplate.delete("permission::allList");*/
        return ResultUtil.success("批量通过id删除数据成功");
    }

    @RequestMapping(value = "/search", method = RequestMethod.GET)
    @ApiOperation(value = "搜索菜单")
    public Result<List<HontPermission>> searchPermissionList(@RequestParam String title){

        List<HontPermission> list = hontPermissionService.findByTitleLikeOrderBySortOrder("%"+title+"%");
        return new ResultUtil<List<HontPermission>>().setData(list);
    }
}
